package org.academic.texteditor.gui;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Container;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.beans.PropertyVetoException;

import javax.swing.JDesktopPane;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;

import org.academic.texteditor.gui.component.JGlassPanel;
import org.academic.texteditor.gui.component.menu.MenuFactory;
import org.academic.texteditor.gui.component.menu.MenuManager;
import org.academic.texteditor.gui.component.toolbar.ToolBarFactory;
import org.academic.texteditor.gui.form.AbstractInternalFrame;
import org.academic.texteditor.gui.form.AbstractModalFrame;
import org.academic.texteditor.gui.form.PageContainerForm;
import org.academic.texteditor.gui.plugin.document.NewDocumentPlugin;
import org.academic.texteditor.gui.plugin.document.OpenDocumentPlugin;
import org.academic.texteditor.gui.plugin.document.SaveDocumentPlugin;

public class PrincipalWindow extends JFrame {

	private static PrincipalWindow instance;
	private JDesktopPane desktopPane;
	private JMenuBar menuBar;
	private PageContainerForm actualDocument;

	private static final long serialVersionUID = -8284436556981539136L;

	private PrincipalWindow() {
		super("::. Document Editor .::");

		desktopPane = new JDesktopPane();

		Container c = getContentPane();
		c.add(desktopPane);

		createMenu();

		c.add(ToolBarFactory.getMain(), BorderLayout.NORTH);
		c.add(ToolBarFactory.getClipBoard(), BorderLayout.EAST);

		new NewDocumentPlugin().initialize(null);
		new OpenDocumentPlugin().initialize(null);
		new SaveDocumentPlugin().initialize(null);

		setSize(730, 530);
		setVisible(true);
		setDefaultCloseOperation(EXIT_ON_CLOSE);

		JGlassPanel glass = new JGlassPanel();
		glass.setSize(getSize());
		setGlassPane(glass);
		glass.setVisible(false);

		setResizable(true);

		ComponentListener listener = new ComponentListener() {
			@Override
			public void componentHidden(ComponentEvent e) {
			}

			@Override
			public void componentMoved(ComponentEvent e) {
			}

			@Override
			public void componentResized(ComponentEvent e) {
				JGlassPanel glassPane = getGlassPane();
				if (glassPane.isVisible()) {
					JInternalFrame[] frames = glassPane.getAllFrames();
					for (JInternalFrame frame : frames) {
						glassPane.centralizeComponent(frame);
					}
				}
			}

			@Override
			public void componentShown(ComponentEvent e) {
			}
		};
		addComponentListener(listener);
	}

	public JMenuBar getMainMenuBar() {
		return menuBar;
	}

	@Override
	public JGlassPanel getGlassPane() {
		return (JGlassPanel) super.getGlassPane();
	}

	private void createMenu() {
		menuBar = new JMenuBar();
		setJMenuBar(menuBar);

		MenuManager.getInstance().setMenuBar(menuBar);

		menuBar.add(MenuFactory.getApplication());
		menuBar.add(MenuFactory.getEdit());
		menuBar.add(MenuFactory.getInsert());
		menuBar.add(MenuFactory.getFormat());
		menuBar.add(MenuFactory.getReference());
	}

	private void enableMenuItem(JMenu component, String name, boolean enable) {
		int count = component.getMenuComponentCount();
		for (int i = 0; i < count; i++) {
			JMenuItem menu = (JMenuItem) component.getMenuComponent(i);
			if (menu.getName().equals(name)) {
				menu.setEnabled(enable);
				break;
			}
			if (menu instanceof JMenu) {
				enableMenuItem((JMenu) menu, name, enable);
			}
		}
	}

	public void enableMenuItem(String name, boolean enable) {
		int count = menuBar.getComponentCount();
		for (int i = 0; i < count; i++) {
			Component c = menuBar.getComponent(i);
			if (c instanceof JMenu) {
				enableMenuItem((JMenu) c, name, enable);
			}
		}
	}

	public void openWindow(AbstractInternalFrame frame) {
		if (frame == null) {
			return;
		}

		boolean found = false;

		int count = desktopPane.getComponentCount();
		for (int i = 0; i < count; i++) {
			if (desktopPane.getComponent(i).equals(frame)) {
				frame = (AbstractInternalFrame) desktopPane.getComponent(i);
				found = true;
				break;
			}
		}

		if (!found) {
			desktopPane.add(frame);
		}

		try {
			frame.setSelected(true);
		} catch (PropertyVetoException e1) {
			e1.printStackTrace();
		}
	}

	public void openModalWindow(AbstractModalFrame frame) {
		JGlassPanel glass = getGlassPane();
		glass.setVisible(true);
		glass.add(frame);
	}

	public void closeModalWindow(AbstractModalFrame frame) {
		JGlassPanel glass = getGlassPane();
		glass.remove(frame);
		glass.setVisible(false);
	}

	public void closeWindow(AbstractInternalFrame frame) {
		try {
			frame.setVisible(false);
			frame.setClosed(true);
			desktopPane.remove(frame);
		} catch (PropertyVetoException e) {
			e.printStackTrace();
		}
	}

	public JDesktopPane getDesktop() {
		return desktopPane;
	}

	public PageContainerForm getActualDocument() {
		return actualDocument;
	}

	public void setActualDocument(PageContainerForm actualDocument) {
		this.actualDocument = actualDocument;
	}

	public static synchronized PrincipalWindow getInstance() {
		if (instance == null) {
			instance = new PrincipalWindow();
		}
		return instance;
	}

}
